Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimize redundant fail checks #118

Merged
merged 4 commits into from
Jun 1, 2021
Merged

Conversation

Mingun
Copy link
Member

@Mingun Mingun commented Apr 27, 2021

Port of my optimization pegjs/pegjs#400, that reduce many dumb comparisons (that is not cut by minifiers). You can see some of them on the parser.js (but enable whitespace-ignored mode on github)

I calculate possible values of the match result and do not generate conditions, that are always true or false and also didn't generate not used constants.

Copy link
Contributor

@StoneCypher StoneCypher left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Creating a good PR is not a simple task, yes. I don't think we should rush to merge unpolished PRs.

The difference, of course, is I'm able to say specifically what isn't acceptable, and why.

lib/compiler/passes/generate-bytecode.js Outdated Show resolved Hide resolved
lib/compiler/passes/generate-bytecode.js Show resolved Hide resolved
lib/compiler/passes/generate-bytecode.js Show resolved Hide resolved
lib/compiler/passes/generate-bytecode.js Show resolved Hide resolved
lib/compiler/passes/generate-bytecode.js Show resolved Hide resolved
lib/compiler/passes/generate-bytecode.js Show resolved Hide resolved
lib/compiler/passes/generate-bytecode.js Outdated Show resolved Hide resolved
lib/compiler/passes/generate-bytecode.js Outdated Show resolved Hide resolved
lib/compiler/passes/generate-bytecode.js Show resolved Hide resolved
lib/compiler/passes/inference-match-result.js Show resolved Hide resolved
Copy link
Member Author

@Mingun Mingun left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@StoneCypher, thanks for review! I'll add some comments describing the overall idea of the generate-bytecode pass, I hope, that saves your time for the next time

lib/compiler/passes/generate-bytecode.js Show resolved Hide resolved
lib/compiler/passes/generate-bytecode.js Outdated Show resolved Hide resolved
lib/compiler/passes/generate-bytecode.js Show resolved Hide resolved
lib/compiler/passes/generate-bytecode.js Show resolved Hide resolved
lib/compiler/passes/generate-bytecode.js Show resolved Hide resolved
lib/compiler/passes/generate-bytecode.js Show resolved Hide resolved
lib/compiler/passes/generate-bytecode.js Outdated Show resolved Hide resolved
lib/compiler/passes/generate-bytecode.js Outdated Show resolved Hide resolved
lib/compiler/passes/generate-bytecode.js Show resolved Hide resolved
lib/compiler/passes/inference-match-result.js Show resolved Hide resolved
@StoneCypher

This comment has been minimized.

@StoneCypher

This comment has been minimized.

@Mingun Mingun force-pushed the inference-match-result branch from 0afeb61 to 913b3f2 Compare May 1, 2021 17:48
@Mingun
Copy link
Member Author

Mingun commented May 1, 2021

I've add some comments, explaining some details how the generate-bytecode pass works and fixed an error: it is impossible to remove always failed alternatives that lead to call of the custom code because it may have side effects. Added tests that proves this (run side-effects in non-matching behavior tests).

Ready for final review.

@StoneCypher

This comment has been minimized.

@Mingun Mingun force-pushed the inference-match-result branch from 913b3f2 to 52ed2d2 Compare May 4, 2021 18:31
@hildjj hildjj added this to the 1.3 milestone May 22, 2021
@Mingun Mingun force-pushed the inference-match-result branch 2 times, most recently from ccf2d2c to 19a1a50 Compare May 27, 2021 16:47
@hildjj hildjj modified the milestones: 1.3, 1.2 May 28, 2021
@hildjj hildjj mentioned this pull request May 28, 2021
3 tasks
@Mingun Mingun force-pushed the inference-match-result branch from 19a1a50 to 36e9b07 Compare May 28, 2021 17:34
Copy link
Contributor

@hildjj hildjj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are all minor comments. One substantive point of discussion, though: shouldn't many of these cases be warnings (or errors if you pass in a "all warnings are errors" flag)? We don't currently have a mechanism for warnings, but if we're going to do multiple errors in #160, could we discuss also adding warnings at the same time?

CHANGELOG.md Outdated Show resolved Hide resolved
lib/compiler/passes/generate-bytecode.js Outdated Show resolved Hide resolved
lib/compiler/passes/generate-bytecode.js Outdated Show resolved Hide resolved
lib/compiler/passes/generate-bytecode.js Outdated Show resolved Hide resolved
lib/compiler/passes/generate-bytecode.js Outdated Show resolved Hide resolved
lib/compiler/passes/generate-bytecode.js Outdated Show resolved Hide resolved
lib/compiler/passes/generate-bytecode.js Outdated Show resolved Hide resolved
lib/compiler/passes/generate-bytecode.js Outdated Show resolved Hide resolved
lib/compiler/passes/generate-bytecode.js Outdated Show resolved Hide resolved
@@ -248,7 +269,10 @@ function generateBytecode(ast) {
return first.concat(...args);
}

function buildCondition(condCode, thenCode, elseCode) {
function buildCondition(match, condCode, thenCode, elseCode) {
if (match > 0) { return thenCode; }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you add constants, they should be used here as well.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@Mingun
Copy link
Member Author

Mingun commented May 30, 2021

Locally fixed all except constants. Will do that tomorrow.

These are all minor comments. One substantive point of discussion, though: shouldn't many of these cases be warnings (or errors if you pass in a "all warnings are errors" flag)? We don't currently have a mechanism for warnings, but if we're going to do multiple errors in #160, could we discuss also adding warnings at the same time?

Yes, always matched/never matched will report warnings when we merge warnings support.

Mingun added 2 commits May 31, 2021 21:31
…or result of parse, when it can be statically determined

The idea in that we calculate expected rules result and use that information when generate bytecode.
Some constructs of the PEG grammar never fail, for example, optional operator `?` or repetition
operator `*`. So it is unnecessary to check their result for the failure.

New pass `inference-match-result.js` adds to the each AST node new integer property `match`, which
represents possible result of matching:
- `<0` - node is never match, for example, `!('a'*)` (negation of the always matched node)
- `=0` - sometimes node matched, sometimes not. This is behavior before that change
- `>0` - node is always matched, for example, `'a'*` (because result is or empty array, or array with some elements)
…hangelog

(review this change with the space changes ignored)
@Mingun Mingun force-pushed the inference-match-result branch from 36e9b07 to 8a4051f Compare May 31, 2021 16:38
@Mingun Mingun requested a review from hildjj May 31, 2021 16:43
@@ -248,7 +270,10 @@ function generateBytecode(ast) {
return first.concat(...args);
}

function buildCondition(condCode, thenCode, elseCode) {
function buildCondition(match, condCode, thenCode, elseCode) {
if (match === ALWAYS_MATCH) { return thenCode; }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This reads a lot easier. thanks for that.

@hildjj
Copy link
Contributor

hildjj commented May 31, 2021

I went to add type tests for MatchResult, and found an error in the compile interface of peg.d.ts. Here's an appended patch that fixes that, and adds the comment I was talking about. Let me know your opinion, please.

hildjj added 2 commits June 1, 2021 22:38
…oesn't need to be an object that gets converted to an array; it can just be an array that gets copied
@Mingun Mingun force-pushed the inference-match-result branch from ed1cb08 to 3a25229 Compare June 1, 2021 17:39
@Mingun
Copy link
Member Author

Mingun commented Jun 1, 2021

Ok. I've just split you commit into two and fix a small incorrectness in you understanding of a situation about possible cycle

@hildjj hildjj merged commit cb7a18b into peggyjs:main Jun 1, 2021
@Mingun Mingun deleted the inference-match-result branch June 1, 2021 18:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants